package com.umpay.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.nio.channels.FileChannel;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

import org.apache.log4j.Logger;

public class FieldableFile {
	private File file;
	private BufferedReader in = null;
	private OutputStreamWriter out = null;
	// private FileWriter out = null;
	private String newlineChar = null;
	private String delim = null;
	private String lineSeparator = System.getProperty("line.separator");
	private int[] flengths = null;
	private static final Logger log = Logger.getLogger(FieldableFile.class);

	public FieldableFile(String paramString) {
		this.file = new File(paramString);
	}

	public String getFilename() {
		return this.file.getName();
	}

	private void open4Read() throws IOException {
		if ((this.in != null) || (this.out != null)) {
			throw new IOException(this.file + "已经打开");
		}
		this.in = new BufferedReader(new InputStreamReader(new FileInputStream(
				this.file), "UTF-8"));
		// this.in = new BufferedReader(new FileReader(this.file));
	}

	private void open4ReadEncode(String encode) throws IOException {
		if ((this.in != null) || (this.out != null)) {
			throw new IOException(this.file + "已经打开");
		}
		this.in = new BufferedReader(new InputStreamReader(new FileInputStream(
				this.file), encode));
		// this.in = new BufferedReader(new FileReader(this.file));
	}
	private void open4Write() throws IOException {
		if ((this.out != null) || (this.in != null)) {
			throw new IOException(this.file + "已经打开");
		}
		this.out = new OutputStreamWriter(new FileOutputStream(this.file),
				"UTF-8");
		// new FileWriter(this.file);
	}

	private void open4WriteEncode(String encode) throws IOException {
		if ((this.out != null) || (this.in != null)) {
			throw new IOException(this.file + "已经打开");
		}
		this.out = new OutputStreamWriter(new FileOutputStream(this.file),
				encode);
		// new FileWriter(this.file);
	}

	private void open4WriteAdd(String encode) throws IOException {
		if ((this.out != null) || (this.in != null)) {
			throw new IOException(this.file + "已经打开");
		}
		this.out = new OutputStreamWriter(
				new FileOutputStream(this.file, true), encode);
		// new FileWriter(this.file);
	}

	/**
	 * 说明：true 为写 false 为读
	 * 对于true：
	 *          mode
	 *          不传递时默认为不追加UTF-8
	 *          传递ADD时默认为UTF-8追加
	 *          同时传递GBK或UTF-8和ADD 为指定的方式
	 * 对于false：
	 *          mode
	 *          不传递时默认为UTF-8
	 *          同时传递GBK或UTF-8为指定的方式
	 *          
	 * @param paramBoolean
	 * @param paramString
	 * @param mode
	 * @throws IOException
	 */
	public void open(boolean paramBoolean, String paramString, String... mode)
			throws IOException {
		if (paramString == null) {
			throw new IOException("delim = null");
		}
		if (paramBoolean) {
			if (mode.length!=0) {
				List<String> list = Arrays.asList(mode);
				if(list.contains("ADD")){
					if(list.contains("GBK")){
						open4WriteAdd("GBK");
					}else {
						open4WriteAdd("UTF-8");
					}
				}else{
					if(list.contains("GBK")){
						open4WriteEncode("GBK");
					}else {
						open4WriteEncode("UTF-8");
					}
				}
			} else {
				open4Write();
			}
		} else {
			if (mode.length!=0) {
				List<String> list = Arrays.asList(mode);
					if(list.contains("GBK")){
						open4ReadEncode("GBK");
					}else {
						open4ReadEncode("UTF-8");
					}
			}else{
				open4Read();
			}
		}
		this.delim = paramString;
	}

	public void open(boolean paramBoolean, int[] paramArrayOfInt)
			throws IOException {
		if (paramArrayOfInt == null) {
			throw new IOException("flengths = null");
		}
		if (paramBoolean) {
			open4Write();
		} else {
			open4Read();
		}
		this.flengths = paramArrayOfInt;
	}

	public void open(String paramString, int[] paramArrayOfInt)
			throws IOException {
		if ((paramArrayOfInt == null) && (paramString == null)) {
			throw new IOException("flengths = null = delim");
		}
		open4Read();
		this.delim = paramString;
		this.flengths = paramArrayOfInt;
	}

	public void close() {
		try {
			if (this.in != null) {
				try {
					this.in.close();
				} catch (IOException localIOException1) {
				}
				this.in = null;
			}
			if (this.out != null) {
				this.out.close();
				this.out = null;
			}
			this.delim = null;
			this.flengths = null;
		} catch (IOException localIOException2) {
			log.info("关闭文件时出错，不抛出异常!" + localIOException2);
		}
	}

	public String readLine() throws IOException {
		return this.in.readLine();
	}

	public String[] lineToFields(String paramString) {
		if (paramString == null) {
			return null;
		}
		if ((this.delim != null) && (this.flengths != null)) {
			return split(paramString, this.delim, this.flengths);
		}
		if (this.delim != null) {
			return split(paramString, this.delim);
		}
		if (this.flengths != null) {
			return split(paramString, this.flengths);
		}
		return null;
	}

	public String[] readFields() throws IOException {
		String str = readLine();
		return lineToFields(str);
	}

	public void setNewLineChar(String paramString) {
		this.newlineChar = paramString;
	}

	public void writeLine(String paramString) throws IOException {
		this.out.write(paramString);
		if (this.newlineChar != null) {
			this.out.write(this.newlineChar);
		} else {
			this.out.write(this.lineSeparator);
		}
	}

	public void insertHead(String paramString) throws IOException {
		if (paramString == null) {
			return;
		}
		this.out.close();
		File localFile = new File(this.file.getAbsolutePath() + ".heading");
		this.out = new FileWriter(localFile);
		writeLine(paramString);
		this.out.flush();
		this.out.close();
		FileOutputStream localFileOutputStream = new FileOutputStream(
				localFile, true);
		FileInputStream localFileInputStream = new FileInputStream(this.file);
		FileChannel localFileChannel1 = localFileInputStream.getChannel();
		FileChannel localFileChannel2 = localFileOutputStream.getChannel();
		long l1 = localFileChannel1.size();
		long l2 = localFileChannel2.transferFrom(localFileChannel1,
				localFile.length(), localFileChannel1.size());
		if (l1 != l2) {
			throw new IOException("src_size[" + l1 + "]<>tf_size[" + l2 + "]");
		}
		localFileChannel1.close();
		localFileChannel2.close();
		localFileInputStream.close();
		localFileOutputStream.close();
		this.file.delete();
		if (!localFile.renameTo(this.file)) {
			throw new IOException("rename " + localFile.getAbsolutePath()
					+ " to " + this.file.getAbsolutePath() + " fail.");
		}
		this.file = new File(this.file.getAbsolutePath());
		this.out = new FileWriter(this.file, true);
	}

	private String[] split(String paramString, int[] paramArrayOfInt) {
		String[] arrayOfString = new String[paramArrayOfInt.length];
		byte[] arrayOfByte = paramString.getBytes();
		int i = 0;
		for (int j = 0; j < paramArrayOfInt.length; j++) {
			if (paramArrayOfInt[j] < 0) {
				if (paramArrayOfInt.length == j + 1) {
					arrayOfString[j] = new String(arrayOfByte, i,
							arrayOfByte.length - i);
					break;
				}
				paramArrayOfInt[j] = Math.abs(paramArrayOfInt[j]);
			}
			arrayOfString[j] = new String(arrayOfByte, i, paramArrayOfInt[j]);
			i += paramArrayOfInt[j];
		}
		return arrayOfString;
	}

	private String[] split(String paramString1, String paramString2,
			int[] paramArrayOfInt) {
		String[] arrayOfString1 = new String[paramArrayOfInt.length];
		String[] arrayOfString2 = split(paramString1, paramString2);
		int i = 0;
		for (int j = 0; j < arrayOfString2.length; j++) {
			byte[] arrayOfByte = arrayOfString2[j].getBytes();
			int k = 0;
			for (int m = i; m < paramArrayOfInt.length; m++) {
				if (paramArrayOfInt[m] < 0) {
					arrayOfString1[(i++)] = new String(arrayOfByte, k,
							arrayOfByte.length - k);
					break;
				}
				arrayOfString1[(i++)] = new String(arrayOfByte, k,
						paramArrayOfInt[m]);
				k += paramArrayOfInt[m];
			}
		}
		return arrayOfString1;
	}

	public static String[] split(String paramString1, String paramString2) {
		LinkedList localLinkedList = new LinkedList();
		int j;
		for (int i = 0;; i = j + paramString2.length()) {
			j = paramString1.indexOf(paramString2, i);
			if (j < 0) {
				localLinkedList.addLast(paramString1.substring(i));
				break;
			}
			localLinkedList.addLast(paramString1.substring(i, j));
		}
		return (String[]) localLinkedList.toArray(new String[localLinkedList
				.size()]);
	}

	public static void main(String[] paramArrayOfString) throws Exception {
		 try
		 {
		 FieldableFile localFieldableFile = new FieldableFile("E:/1258.csv");
		 localFieldableFile.open(true, ",","ADD","GBK");
		 localFieldableFile.writeLine("KKKK你妈妈不追加");
		 localFieldableFile.close();
		// localFieldableFile.writeFields(new String[] {
		// "=============start开始=================" });
		// for (int i = 0; i < 10; i++)
		// {
		// localFieldableFile.writeFields(new String[] { "111", "cdef", "adsf"
		// });
		// localFieldableFile.writeFields(new String[] { "222", "cdef", "adsf"
		// });
		// }
		// // localFieldableFile.insertHead("this head1");
		// // localFieldableFile.insertHead("this head2");
		// // localFieldableFile.insertHead("this head3");
		// // localFieldableFile.insertHead("this head4");
		// // localFieldableFile.insertHead("this head5");
		// // localFieldableFile.insertHead("this head6");
		// localFieldableFile.writeLine("=============tail结束================");
		// localFieldableFile.close();
		 }
		 catch (Exception localException)
		 {
		 localException.printStackTrace();
		 }
		
	}
}
